package com.zxy.supplier_system.server.service

import com.zxy.supplier_system.server.controller.GoodsBrandController
import com.zxy.supplier_system.server.entity.*
import com.zxy.supplier_system.server.repository.GoodsBrandRepository
import com.zxy.supplier_system.server.repository.GoodsRepository
import com.zxy.supplier_system.server.repository.SystemServiceRepository
import com.zxy.supplier_system.server.utils.orElse404
import com.zxy.supplier_system.server.utils.toIntIdAndName
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class GoodsBrandService(
    private val goodsBrandRepository: GoodsBrandRepository,
    private val goodsRepository: GoodsRepository,
    private val systemServiceService: SystemServiceService,
    private val employeeOperateRecordService: EmployeeOperateRecordService,
) {


    @Transactional(readOnly = true)
    fun queryGoodsBrands(
        pageable: Pageable,
        queryGoodsBrandsRequest: GoodsBrandController.QueryGoodsBrandsRequest
    ): Page<GoodsBrandController.QueryGoodsBrandsResponse> {
        return this.goodsBrandRepository.findAll(
            GoodsBrandRepository.Specifications.fromQueryGoodsBrandsRequest(queryGoodsBrandsRequest).and(
                SystemServiceRepository.Specifications.systemServiceEquals(
                    { root -> root },
                    systemServiceService.getCurrentSystemService()
                )

            ), pageable
        ).map {
            GoodsBrandController.QueryGoodsBrandsResponse(
                it.name,
                it.id,
                this.goodsRepository.countAllByBrand(it),
                it.group?.toIntIdAndName(),
                it.factory?.toIntIdAndName(),
                it.tags.map { t->t.toIntIdAndName() },
                it.disable,
            )
        }
    }

    @Transactional
    fun updateGoodsBrand(id: Int, updateGoodsBrandRequest: GoodsBrandController.UpdateGoodsBrandRequest) {
        val data = this.goodsBrandRepository.findByIdOrNull(id).orElse404()
        data.name = updateGoodsBrandRequest.name
        updateGoodsBrandRequest.groupId?.let {
            data.group = GoodsBrandGroup().apply {
                this.id = it
            }
        }
        updateGoodsBrandRequest.factoryId?.let {
            data.factory = Factory().apply {
                this.id = it
            }
        }
        data.tags = updateGoodsBrandRequest.tagIds.map {
            GoodsBrandTag().apply {
                this.id = it
            }
        }.toMutableList()

        this.goodsBrandRepository.save(data)
        this.employeeOperateRecordService.updateGoodsBrand(data)
    }

    @Transactional
    fun createGoodsBrand(updateGoodsBrandRequest: GoodsBrandController.UpdateGoodsBrandRequest) {
        val goodsBrand = this.goodsBrandRepository.save(GoodsBrand().apply {
            name = updateGoodsBrandRequest.name
            updateGoodsBrandRequest.groupId?.let {
                group = GoodsBrandGroup().apply {
                    this.id = it
                }
            }
            systemService = systemServiceService.getCurrentSystemService()
            updateGoodsBrandRequest.factoryId?.let {
                factory = Factory().apply {
                    this.id = it
                }
            }
            tags = updateGoodsBrandRequest.tagIds.map {
                GoodsBrandTag().apply {
                    this.id = it
                }
            }.toMutableList()
        })
        this.employeeOperateRecordService.createGoodsBrand(goodsBrand)
    }

    @Transactional
    fun deleteGoodsBrand(id: Int) {
        this.goodsBrandRepository.deleteById(id)
    }


    @Transactional(readOnly = true)
    fun getAllGoodsBrands(): List<GoodsBrandController.GoodsBrandSummary> {
        return this.goodsBrandRepository.findAllBySystemServiceOrderByGroup_Id(systemServiceService.getCurrentSystemService()).map {
            GoodsBrandController.GoodsBrandSummary(it.id, it.name)
        }
    }

    @Transactional
    fun disable(id: Int) {
        val goodsBrand = this.goodsBrandRepository.findByIdAndSystemService(id,systemServiceService.getCurrentSystemService()).orElse404()
        goodsBrand.disable = true
        this.goodsBrandRepository.save(goodsBrand)
        this.employeeOperateRecordService.disableGoodsBrand(goodsBrand)
    }

    @Transactional
    fun enable(id: Int) {
        val goodsBrand = this.goodsBrandRepository.findByIdAndSystemService(id,systemServiceService.getCurrentSystemService()).orElse404()
        goodsBrand.disable = false
        this.goodsBrandRepository.save(goodsBrand)
        this.employeeOperateRecordService.enableGoodsBrand(goodsBrand)
    }


}
